package app.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
import app.log.APPLog;


public class MyWorkspace extends ViewGroup {
    
    static final String TAG = MyWorkspace.class.getSimpleName();
    
    private final int TOUCH_STATE_REST = 0;
    private final int TOUCH_STATE_SCROLLING = 1;
    
    private final int INVALID_SCREEN = -1;
    
    /**
     * 当前的触摸状态
     */
    private int mTouchState = TOUCH_STATE_REST;

	/**
	 * 手指触碰屏幕的x坐标
	 */
	private float mLastMotionX;
	
	private int mNextScreen = INVALID_SCREEN;
	
	private Scroller mScroller;
	
	/**
	 * 当前正在显示
	 */
	private int mCurrentScreen   = 0;
	
	/**
	 * 屏幕切换监听器
	 */
	private OnScreenChangeListener onScreenChangeListener;
	
	private int mTouchSlop;

	/**
	 * 速度检测器
	 */
	private VelocityTracker mVelocityTracker;
	
	private float mScale = 1.0f;
	
	/**
	 * 标识当前是否允许用户滑动界面
	 */
	private boolean mEnableScrooler = true;
	
	public MyWorkspace(Context context) {
		super(context);
		init();
	}
	
	public MyWorkspace(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public MyWorkspace(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	private void init() {
		mScroller = new Scroller(getContext());
		
		ViewConfiguration configuration = ViewConfiguration.get(getContext());
		mTouchSlop = configuration.getScaledTouchSlop();
	}
	
	/**
	 * 是否允许用户滑动
	 * @param enableScroller true 表示可以滑动，false表示不能滑动
	 */
	public void setEnableScroller(boolean enableScroller) {
		mEnableScrooler = enableScroller;
	}

//    @Override
//    protected void dispatchDraw(Canvas canvas) {
//        
//        boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN
//            && mScale > 0.999f;
//            
//        if (fastDraw) {
//            drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
//        } else {
//            long drawTime = getDrawingTime();
//            
//            int pre = mCurrentScreen - 1;
//            int next = mCurrentScreen + 1;
//            
//            if (pre >= 0) {
//                drawChild(canvas, getChildAt(pre), drawTime);
//            }
//            
//            if (next < getChildCount()) {
//                drawChild(canvas, getChildAt(next), drawTime);
//            }
//            
//            drawChild(canvas, getChildAt(mCurrentScreen), drawTime);
//        }
//    }

    @Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), 0);
			postInvalidate();
		} else if (mNextScreen != INVALID_SCREEN){
		    mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
		    mNextScreen = INVALID_SCREEN;
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
		// The children are given the same width and height as the workspace
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
		}
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childLeft = 0;
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != View.GONE) {
				final int childWidth = child.getMeasuredWidth();
				child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
				childLeft += childWidth;
			}
		}
	}
	
	@Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
	    final int action = ev.getAction();

	    if (action == MotionEvent.ACTION_MOVE && mTouchState != TOUCH_STATE_REST){ 
	        return true;
	    }
	    
	    final float x = ev.getX();
	    
	    switch (action) {
	        case MotionEvent.ACTION_MOVE:
	            int xDiff = (int) Math.abs(x - mLastMotionX);
	            
	            if (xDiff > mTouchSlop) {
	                mTouchState = TOUCH_STATE_SCROLLING;
	            }
	            
	            break;
	        case MotionEvent.ACTION_DOWN:
	            mLastMotionX = x;
//	            if (!mScroller.isFinished()) {
//	            	mScroller.abortAnimation();
//	            }
	            mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
	            break;
	        case MotionEvent.ACTION_CANCEL:
	        case MotionEvent.ACTION_UP:
	            mTouchState = TOUCH_STATE_REST;
	            break;
	    }
	    
	    APPLog.i(TAG, "onInterceptTouchEvent return :" + (mTouchState != TOUCH_STATE_REST));
	    
        return mTouchState != TOUCH_STATE_REST;
    }

    public boolean onTouchEvent(MotionEvent event) {
		Log.i("zbkc", "workspace OnTouch");
		
		if (!mEnableScrooler) {
			return false;
		}
		
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
		
		int action = event.getAction();
		
		float x = event.getX();
		
		switch (action) {
		case MotionEvent.ACTION_DOWN:
		    
		    Log.i("zbkc", "nextScreen:" + mNextScreen);
		    
		    if (!mScroller.isFinished()) {
		        mScroller.abortAnimation();
		    }
		    
			mLastMotionX = x;
			break;
		case MotionEvent.ACTION_MOVE:
		    
		    mTouchState = TOUCH_STATE_SCROLLING;
		    
			/*　拖动的距离　*/
			int deltaX = (int) (mLastMotionX - x);
			mLastMotionX = x;
			
			if (mCurrentScreen == 0 && deltaX < 0 && getScrollX() < 0) {
			    deltaX = (int) (deltaX / 2.5);
			}
			
			if (mCurrentScreen == getChildCount() -1 && deltaX > 0 && getScrollX() > getWidth() * (getChildCount() -1)) {
			    deltaX = (int) (deltaX / 2.5);
			}
			
			/*　手指滑动的时候,屏幕跟着滑动　*/
			scrollBy(deltaX, 0);
			break;
		case MotionEvent.ACTION_UP:
			
			mTouchState = TOUCH_STATE_REST;
			
			/*　速度检测器　*/
			final VelocityTracker velocityTracker = mVelocityTracker;
			velocityTracker.computeCurrentVelocity(600);
			int velocityX = (int) velocityTracker.getXVelocity();
			if (velocityX > 500) {
				snapToScreem(mCurrentScreen - 1);
			} else if (velocityX < -500) {
				snapToScreem(mCurrentScreen  + 1);
			} else {
				/*手指松开时候屏幕自动选择目标屏滑动*/
				snapToDestination();
			}
		
			break;
			
		case MotionEvent.ACTION_CANCEL:
		    mTouchState = TOUCH_STATE_REST;
		    break;
		}
		return true;
	}
	
	private void snapToDestination() {
		/*
		 *　根据手指松开的位置计算该跳到哪一屏
		 *　算法:
		 *　屏幕编号(以0开始)=(当前ScrollX的位置　+　半个屏幕的宽度)　/　屏幕的宽度 
		 */
		int sreemWidth = getWidth();
		int whichScreem = (getScrollX() + sreemWidth / 2) / sreemWidth;
		
		/*滑动到目标屏*/
		snapToScreem(whichScreem);
	}
	
	public void snapToScreem(int whichScreen) {
		whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
		
		mNextScreen = whichScreen;
		
		if (whichScreen != mCurrentScreen) {
			mCurrentScreen = whichScreen;
			if (onScreenChangeListener != null ) {
				onScreenChangeListener.onScreenChange(whichScreen);
			}
		}
		
		int newX = whichScreen * (getWidth() == 0 ? 800 : getWidth() );
		int delta = newX - getScrollX();
		
		int duration = Math.abs(delta) * 2;
		if (duration > 1000) {
		    duration = 1000;
		}
		
		mScroller.startScroll(getScrollX(), 0, delta, 0, duration);
		invalidate();
	}

	/**
	 * 当前显示的屏幕
	 * @return
	 */
	public int getCurrentScreen() {
		return mCurrentScreen;
	}
	
	public void setOnScreenChangeListener(OnScreenChangeListener onScreenChangeListener) {
		this.onScreenChangeListener = onScreenChangeListener;
	}

	/**
	 * 屏幕切换监听器
	 * @author xiaofanqing
	 *
	 */
	public interface OnScreenChangeListener {
		public void onScreenChange(int screen);
	}

}
